package com.ms.service.module.zone.action;

import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ms.game.itembox.ItemCommand;
import com.ms.game.itembox.SetCrystalCommand;
import com.ms.game.lobby.command.ContinueRewardCommand;
import com.ms.game.lobby.command.DoorManNotifyCommand;
import com.ms.game.lobby.command.JackpotNotifyCommand;
import com.ms.game.lobby.command.LobbyDebugCommand;
import com.ms.game.rebate.GetRebateCommand;
import com.ms.player.Player;
import com.ms.player.PlayerNickNameParser;
import com.ms.player.SetLevelCommand;
import com.ms.service.module.baccarat.BacrCommand;
import com.ms.service.module.gamelog.FlushDbLogCommand;
import com.ms.service.module.zone.command.AccountCommand;
import com.ms.service.module.zone.command.BasicDebugCommand;
import com.ms.service.module.zone.command.FwdCmdCommand;
import com.ms.service.module.zone.command.HelpCommand;
import com.ms.service.module.zone.command.LevelUpCommand;
import com.ms.service.module.zone.command.TestCommand;
import com.ms.service.module.zone.db.DebugCommandLogModel;
import com.xpec.c4.game.datamanager.agent.money.AddMoneyCommand;
import com.xpec.c4.game.datamanager.agent.money.WinMoneyCommand;
import com.xpec.c4.game.login.command.FakeLoginCommand;
import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.message.MessageTypes;
import com.xpec.c4.service.annotations.MessageType;
import com.xpec.c4.service.annotations.Name;
import com.xpec.c4.service.common.BaseMessageAction;
import com.xpec.c4.service.contexts.ScopeType;
import com.xpec.c4.service.ioc.IocContainer;
import com.xpec.c4.service.module.ModuleCommand;
import com.xpec.c4.service.module.PropertyKey;
import com.xpec.c4.service.module.ServerProperties;

/**
 * GM调试工具
 * 
 * @author lipeilin
 * @2010-9-8下午04:21:27
 * 
 */
@Name(scopeType = ScopeType.SESSION)
public class DebugCommandAction extends BaseMessageAction {

	private final static Log log = LogFactory.getLog(DebugCommandAction.class);

	// 回應結果字串

	/** 無使用權限 */
	private static final String PermissionDenied = "Permission denied.";

	/** 指令錯誤 */
	private static final String CommandInvalid = "Command not found.";

	/**
	 * 命令列表
	 */
	public final static HashMap<String, Class<? extends BasicDebugCommand>> gmCommands = new HashMap<String, Class<? extends BasicDebugCommand>>();
	public final static HashMap<String, String> gmCommandDescs = new HashMap<String, String>();
	public final static HashMap<String, String> gmCommandShortDescs = new HashMap<String, String>();

	static {
		setGmCommand(HelpCommand.class);
		setGmCommand(JackpotNotifyCommand.class);
		setGmCommand(AddMoneyCommand.class);
		setGmCommand(WinMoneyCommand.class);
		setGmCommand(ItemCommand.class);
		setGmCommand(TestCommand.class);
		setGmCommand(LevelUpCommand.class);
		setGmCommand(FlushDbLogCommand.class);
		setGmCommand(DoorManNotifyCommand.class);
		setGmCommand(FwdCmdCommand.class);
		setGmCommand(FakeLoginCommand.class);
		setGmCommand(ContinueRewardCommand.class);
		setGmCommand(SetLevelCommand.class);
		setGmCommand(GetRebateCommand.class);
		setGmCommand(SetCrystalCommand.class);
		setGmCommand(LobbyDebugCommand.class);
		setGmCommand(ModuleCommand.class);
		setGmCommand(AccountCommand.class);
		setGmCommand(BacrCommand.class);
	}

	/**
	 * 命令类设置
	 * 
	 * @param command
	 * 
	 * @author lipeilin
	 * @2011-3-27 下午03:14:30
	 */
	private static void setGmCommand(Class<? extends BasicDebugCommand> command) {
		BasicDebugCommand c;
		try {
			c = command.newInstance();
			gmCommands.put(c.getName(), command);
			gmCommandDescs.put(c.getName(), c.getDescription());
			gmCommandShortDescs.put(c.getName(), c.getShortDescription());
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	/**
	 * DEBUG命令处理
	 * 
	 * @param cmd
	 *            命令
	 * 
	 * @author lipeilin
	 * @2010-9-10下午06:27:26
	 */
	@MessageType(typeCode = MessageTypes.C_ZONE_DEBUG_COMMAND_REQUEST)
	public void debugCommand(String cmd) {
		Player player = getPlayer();
		if (player == null)
			return;
		log.info("gm debug command: " + cmd + " player: " + player);

		boolean isUseCommand = false;

		if (ServerProperties.getBoolean(PropertyKey.DebugEnable, false)) {
			isUseCommand = true;
		}

		DebugCommandLogModel model = new DebugCommandLogModel();
		model.setAccountId(player.getAccountId().toString());
		model.setPlayerId(player.getGuid().toString());
		model.setPlayerName(PlayerNickNameParser.mergeNickName(player.getName(), player.getNameNumber()));
		model.setModuleId(getModuleID());
		model.setCommandArgument(cmd);
		getModule().saveDbLog(model);

		if (isUseCommand) {
			if (cmd == null || cmd.length() == 0) {
				return;
			}
			cmd = cmd.trim();

			// 去掉重复空格的
			while (cmd.contains("  ")) {
				cmd = cmd.replace("  ", " ");
			}

			String[] args = cmd.split(" ");

			String name = args[0];

			// 角色是否有此权限
			if (isUseCommand) {
				// 先把到的命令 echo 回去
				BasicDebugCommand.sendDebugCommandResponse(sessionID, cmd);

				// 選找對應的 class
				Class<? extends BasicDebugCommand> clazz = gmCommands.get(name);

				if (clazz == null) {
					BasicDebugCommand.sendDebugCommandResponse(sessionID, CommandInvalid);
					return;
				}

				BasicDebugCommand comObject = IocContainer.createObject(clazz);
				comObject.setCommand(cmd);
				comObject.setCommandValue(args);
				comObject.setPlayer(player);

				// 命令内部检查
				if (comObject.available()) {
					String result = comObject.execute();

					// 结果发送给Client
					if (GameUtility.isHaveString(result)) {
						BasicDebugCommand.sendDebugCommandResponse(sessionID, result);
					}
				} else {
					BasicDebugCommand.sendDebugCommandResponse(sessionID, PermissionDenied);
				}
			} else {
				BasicDebugCommand.sendDebugCommandResponse(sessionID, PermissionDenied);
			}
		}
	}
}
